import sys
from PySide6.QtWidgets import QApplication, QGroupBox, QVBoxLayout, QHBoxLayout, QListWidget, QLineEdit, QPushButton, QLabel, QListWidgetItem
from PySide6.QtCore import Qt, Slot

class FieldSelectBox(QGroupBox):
    DEFAULT_OPTIONAL_COLUMNS = ['发票代码', '开票日期', '合计金额', '校验码', '税率', '合计税额', 
                                '购买方识别号', '销售方识别号', '发票名称', '购买方名称', 
                                '销售方名称', '备注', '规格型号', '数量', '单价', '金额', '税额']
    DEFAULT_DISPLAY_COLUMNS = ['发票号码', '价税合计', '服务名称']

    def __init__(self, style: str = ''):
        super().__init__()
        self.setStyleSheet(style)
        self.setMinimumSize(300, 250)
        self.all_list_widget = {}
        self.all_label = {}
        self.setup_ui()


    def setup_ui(self):
        self.setTitle('发票字段选择')

        # 主布局
        main_layout = QVBoxLayout(self)

        # 可选字段部分
        optional_layout = QVBoxLayout()
        num_optional_columns = len(self.DEFAULT_OPTIONAL_COLUMNS)
        self.optional_label = QLabel(f'可选字段 ({num_optional_columns}/{num_optional_columns})')  # 设置初始值
        self.optional_label.setObjectName('optional_label')
        optional_layout.addWidget(self.optional_label)

        self.optional_search = QLineEdit()
        self.optional_search.setObjectName('optional_search')
        self.optional_search.textChanged.connect(self.filter_columns)
        self.optional_search.textChanged.connect(self.update_count)
        optional_layout.addWidget(self.optional_search)

        self.optional_columns = QListWidget()
        self.optional_columns.setObjectName('optional_columns')
        self.optional_columns.setSelectionMode(QListWidget.MultiSelection)
        for column in self.DEFAULT_OPTIONAL_COLUMNS:
            item = self.create_checkable_item(column)
            self.optional_columns.addItem(item)
        self.optional_columns.itemClicked.connect(self.toggle_check_state)  # 连接点击事件
        optional_model = self.optional_columns.model()
        optional_model.setObjectName('optional_model')
        optional_model.rowsInserted.connect(self.update_count)  # 监听项数量变化
        optional_model.rowsRemoved.connect(self.update_count)  # 监听项数量变化
        optional_layout.addWidget(self.optional_columns)

        # 输出字段部分
        display_layout = QVBoxLayout()
        num_display_columns = len(self.DEFAULT_DISPLAY_COLUMNS)
        self.display_label = QLabel(f'输出字段 ({num_display_columns}/{num_display_columns})')
        self.display_label.setObjectName('display_label')
        display_layout.addWidget(self.display_label)

        self.display_search = QLineEdit()
        self.display_search.setObjectName('display_search')
        self.display_search.textChanged.connect(self.filter_columns)
        self.display_search.textChanged.connect(self.update_count)
        display_layout.addWidget(self.display_search)

        self.display_columns = QListWidget()
        self.display_columns.setObjectName('display_columns')
        self.display_columns.setSelectionMode(QListWidget.MultiSelection)
        for column in self.DEFAULT_DISPLAY_COLUMNS:
            item = self.create_checkable_item(column)
            self.display_columns.addItem(item)
        self.display_columns.itemClicked.connect(self.toggle_check_state)  # 连接点击事件
        display_model = self.display_columns.model()
        display_model.setObjectName('display_model')
        display_model.rowsInserted.connect(self.update_count)  # 监听项数量变化
        display_model.rowsRemoved.connect(self.update_count)  # 监听项数量变化
        display_layout.addWidget(self.display_columns)

        # 将两个listwidget加入self.all_list_widget
        self.all_list_widget['optional_columns'] = self.optional_columns
        self.all_list_widget['display_columns'] = self.display_columns
        # 将两个label加入self.all_label
        self.all_label['optional_label'] = self.optional_label
        self.all_label['display_label'] = self.display_label

        # 移动按钮部分
        button_layout = QVBoxLayout()
        move_selected_to_display_button = QPushButton('>')
        move_all_to_display_button = QPushButton('>>')
        move_selected_to_optional_button = QPushButton('<')
        move_all_to_optional_button = QPushButton('<<')

        move_selected_to_display_button.clicked.connect(self.move_item_to_opposite)
        move_selected_to_optional_button.clicked.connect(self.move_item_to_opposite)
        move_all_to_display_button.clicked.connect(self.move_item_to_opposite)
        move_all_to_optional_button.clicked.connect(self.move_item_to_opposite)

        # 设置按钮之间的间距
        button_layout.setSpacing(10)  # 调整按钮之间的间距

        # 添加按钮到布局，并均匀分布
        button_layout.addStretch(2)  # 顶部拉伸（因子为 2）
        button_layout.addWidget(move_selected_to_display_button)
        button_layout.addWidget(move_all_to_display_button)
        button_layout.addWidget(move_selected_to_optional_button)
        button_layout.addWidget(move_all_to_optional_button)
        button_layout.addStretch(1)  # 底部拉伸（因子为 1）

        # 将可选字段、按钮、输出字段放入一个水平布局
        columns_layout = QHBoxLayout()
        columns_layout.addLayout(optional_layout)
        columns_layout.addLayout(button_layout)
        columns_layout.addLayout(display_layout)

        # 重置按钮
        reset_button = QPushButton('重置')
        reset_button.setFixedSize(80, 30)          # 设置按钮的固定大小
        reset_button.clicked.connect(self.reset_columns)

        # 添加子布局到主布局
        main_layout.addLayout(columns_layout)
        main_layout.addWidget(reset_button, alignment=Qt.AlignRight)

    def create_checkable_item(self, text):
        """创建一个带有复选框的 QListWidgetItem"""
        item = QListWidgetItem(text)
        item.setCheckState(Qt.Unchecked)  # 默认未选中
        return item

    @Slot(QListWidgetItem)
    def toggle_check_state(self, item):
        """切换复选框状态"""
        if item.checkState() == Qt.Checked:
            item.setCheckState(Qt.Unchecked)
        else:
            item.setCheckState(Qt.Checked)

    @Slot()
    def filter_columns(self):
        current_le = self.sender()
        name = current_le.objectName().replace('search', 'columns')
        current_columns = self.all_list_widget[name]
        search_text = current_le.text().lower()
        for i in range(current_columns.count()):
            item = current_columns.item(i)
            item.setHidden(search_text not in item.text().lower())

    @Slot()
    def move_item_to_opposite(self):
        """将item从当前listwidget移动到另一个listwidget"""
        current_btn_txt = self.sender().text()
        key_value = {'>' : {'take_columns': self.optional_columns, 'add_columns': self.display_columns},
                     '<': {'take_columns': self.display_columns, 'add_columns': self.optional_columns}}
        key = key_value[current_btn_txt[0]]
        take_columns = key['take_columns']
        add_columns = key['add_columns']
        if len(current_btn_txt) == 1:
            for i in range(take_columns.count() - 1, -1, -1):  # 从后往前遍历，避免索引问题
                item = take_columns.item(i)
                if item.checkState() == Qt.Checked:  # 只移动选中的项
                    add_columns.addItem(self.create_checkable_item(item.text()))
                    take_columns.takeItem(i)
        else:
            while take_columns.count() > 0:
                item = take_columns.item(0)
                add_columns.addItem(self.create_checkable_item(item.text()))
                take_columns.takeItem(0)

    @Slot()
    def reset_columns(self):
        """重置列到初始状态"""
        self.optional_columns.clear()
        self.display_columns.clear()
        for column in self.DEFAULT_OPTIONAL_COLUMNS:
            item = self.create_checkable_item(column)
            self.optional_columns.addItem(item)
        for column in self.DEFAULT_DISPLAY_COLUMNS:
            item = self.create_checkable_item(column)
            self.display_columns.addItem(item)

    def confirm_configuration(self):
        """确认配置，打印已选输出字段"""
        selected_columns = [self.display_columns.item(i).text() for i in range(self.display_columns.count())]
        print("已选输出字段:", selected_columns)

    @Slot()
    def update_count(self):
        """更新计数"""
        current_widget = self.sender()
        initial_name = current_widget.objectName().split('_')[0]
        # if initial_name == None:        # QAbstractItemModel
        #     return  
        list_widget = self.all_list_widget[f'{initial_name}_columns']
        label = self.all_label[f'{initial_name}_label']
        total_count = list_widget.count()
        visible_count = sum(not list_widget.item(i).isHidden() for i in range(total_count))
        label.setText(f'输出字段 ({visible_count}/{total_count})' if list_widget == self.display_columns 
                 else f'可选字段 ({visible_count}/{total_count})')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = FieldSelectBox()
    ex.show()
    sys.exit(app.exec())